Node.js Raspberry Pi RGB LED with WebSocket

PWM এবং WebSocket ব্যবহার করে একটি RGB LED নিয়ন্ত্রণ করতে শিখুন

পালস-প্রস্থ মড্যুলেশন ব্যবহার করে

আগের অধ্যায়ে আমরা শিখেছি কিভাবে WebSocket ব্যবহার করতে হয় এবং কিভাবে GPIO ব্যবহার করে LED চালু ও বন্ধ করতে হয়।

এতে আমরা PWM (Pulse-Width Modulation) সহ একটি RGB LED ব্যবহার করব WebSocket এর মাধ্যমে ব্যবহারকারীর ইনপুটের উপর ভিত্তি করে বিভিন্ন রং প্রদর্শন করতে।

একটি RGB LED হল 3টি ভিন্ন রঙের একটি LED। এটিতে একটি লাল, সবুজ এবং নীল LED (RGB LED) রয়েছে।

এবং PWM ব্যবহার করে, আপনি 3টি LED-এর পৃথক তীব্রতা সেট করতে পারেন। এটি আমাদের একটি রঙ তৈরি করতে তাদের মিশ্রিত করার অনুমতি দেবে।

আমাদের কি দরকার?

এই অধ্যায়ে আমরা ওয়েব পেজ থেকে WebSocket এর মাধ্যমে RGB LED নিয়ন্ত্রণ করার একটি উদাহরণ তৈরি করব।

এর জন্য আপনার প্রয়োজন:

বিভিন্ন উপাদানের বর্ণনার জন্য উপরের তালিকার লিঙ্কগুলিতে ক্লিক করুন।

💡দ্রষ্টব্য:

LED এর প্রকারের উপর নির্ভর করে আপনি যে প্রতিরোধকটি ব্যবহার করছেন তা আমরা যা ব্যবহার করি তার থেকে আলাদা হতে পারে। বেশিরভাগ ছোট LED-এর জন্য শুধুমাত্র একটি ছোট রোধের প্রয়োজন হয়, প্রায় 200-500 ওহম। আপনি যে সঠিক মানটি ব্যবহার করেন তা সাধারণত গুরুত্বপূর্ণ নয়, তবে প্রতিরোধকের মান যত ছোট হবে, LED তত উজ্জ্বল হবে।

পিগপিও মডিউল ইনস্টল করুন

পূর্বে, আমরা "অনঅফ" মডিউল ব্যবহার করতাম, যা শুধুমাত্র চালু এবং বন্ধ করার জন্য ভাল কাজ করে। এখন আমরা LED এর শক্তি সেট করতে চাই, তাই আমাদের একটু বেশি কার্যকারিতা সহ একটি GPIO মডিউল প্রয়োজন।

আমরা "pigpio" Node.js মডিউল ব্যবহার করব কারণ এটি PWM এর অনুমতি দেয়।

PWM এর সাহায্যে একটি LED এর তীব্রতা 0 থেকে 255 পর্যন্ত সেট করা যেতে পারে।

"pigpio" Node.js মডিউলটি পিগপিও সি লাইব্রেরির উপর ভিত্তি করে তৈরি।

আপনি যদি রাস্পবিয়ানের "লাইট" সংস্করণ ব্যবহার করেন তবে এটি প্রায়শই অন্তর্ভুক্ত করা হয় না এবং ম্যানুয়ালি ইনস্টল করা আবশ্যক৷

আপনার সিস্টেম প্যাকেজ তালিকা আপডেট করুন:

pi@jassifteam:~ $ sudo apt-get update

পিগপিও সি লাইব্রেরি ইনস্টল করুন:

pi@jassifteam:~ $ sudo apt-get install pigpio

এখন আমরা npm ব্যবহার করে "pigpio" Node.js মডিউল ইনস্টল করতে পারি:

pi@jassifteam:~ $ npm install pigpio

এখন "পিগপিও" মডিউলটি ইনস্টল করা উচিত এবং আমরা রাস্পবেরি পাই এর GPIO এর সাথে যোগাযোগ করতে এটি ব্যবহার করতে পারি।

⚠️দ্রষ্টব্য:

যেহেতু "পিগপিও" মডিউলটি পিগপিও সি লাইব্রেরি ব্যবহার করে, তাই হার্ডওয়্যার পেরিফেরালগুলি (যেমন GPIO) অ্যাক্সেস করার জন্য এটির রুট/সুডো সুবিধার প্রয়োজন।

সার্কিট নির্মাণ

এখন আমাদের ব্রেডবোর্ডে সার্কিট তৈরি করার সময়।

আপনি যদি ইলেকট্রনিক্সে নতুন হন, আমরা রাস্পবেরি পাই এর জন্য পাওয়ার সাপ্লাই বন্ধ করার পরামর্শ দিই। এছাড়াও এটির ক্ষতি এড়াতে একটি অ্যান্টি-স্ট্যাটিক ম্যাট বা গ্রাউন্ডিং স্ট্র্যাপ ব্যবহার করুন।

রাস্পবেরি পাই সঠিকভাবে বন্ধ করতে কমান্ডটি ব্যবহার করুন:

pi@jassifteam:~ $ sudo shutdown -h now

রাস্পবেরি পাই-তে এলইডি ফ্ল্যাশিং বন্ধ করার পরে, রাস্পবেরি পাই থেকে পাওয়ার প্লাগটি টানুন (বা এটির সাথে সংযুক্ত পাওয়ার স্ট্রিপটি বন্ধ করুন)।

প্লাগটি সঠিকভাবে বন্ধ না করে টানলে মেমরি কার্ডের ক্ষতি হতে পারে।

আপনার একটি সাধারণ অ্যানোড বা একটি সাধারণ ক্যাথোড থাকুক না কেন, এই সার্কিটগুলি তৈরিতে RGB LED গুরুত্বপূর্ণ:

আপনি আপনার প্রদানকারীর সাথে চেক করতে পারেন, অথবা নিজে পরীক্ষা করতে পারেন:

GND এবং 3.3V পিনের সাথে তারগুলি সংযুক্ত করুন। RGB LED এর লম্বা পায়ের সাথে GND কানেক্ট করুন এবং অন্য কোন পায়ের সাথে 3.3 V কানেক্ট করুন। যদি এটি আলোকিত হয়, আপনার RGB LED একটি সাধারণ ক্যাথোড আছে। যদি না হয়, এটি একটি সাধারণ anode আছে.

বিল্ডিং সার্কিট - সাধারণ ক্যাথোড

Building the Circuit - Common Cathode diagram would be here

বিল্ডিং সার্কিট - সাধারণ অ্যানোড

Building the Circuit - Common Anode diagram would be here

রাস্পবেরি পাই এবং Node.js RGB LED এবং WebSocket স্ক্রিপ্ট

"nodetest" ডিরেক্টরিতে যান এবং "rgbws.js" নামে একটি নতুন ফাইল তৈরি করুন:

pi@jassifteam:~ $ nano rgbws.js

ফাইলটি এখন বিল্ট-ইন ন্যানো এডিটর দিয়ে খোলা এবং সম্পাদনা করা যেতে পারে।

নিম্নলিখিত লিখুন বা পেস্ট করুন:

rgbws.js

const Gpio = require('pigpio').Gpio;
const http = require('http').createServer(handler);
const fs = require('fs');
const io = require('socket.io')(http);
const path = require('path');

// Use GPIO pins for RGB LED (adjust based on your wiring)
const redLed = new Gpio(17, {mode: Gpio.OUTPUT});
const greenLed = new Gpio(27, {mode: Gpio.OUTPUT});
const blueLed = new Gpio(22, {mode: Gpio.OUTPUT});

// Set initial color to off
let currentColor = { red: 0, green: 0, blue: 0 };

http.listen(8080, () => {
  console.log('WebSocket server running on port 8080');
});

function handler(req, res) {
  let filePath = req.url === '/' ? '/public/rgb.html' : '/public' + req.url;
  
  fs.readFile(__dirname + filePath, (err, data) => {
    if (err) {
      res.writeHead(404, {'Content-Type': 'text/html'});
      return res.end('404 Not Found');
    }
    
    const ext = path.extname(filePath);
    let contentType = 'text/html';
    
    switch (ext) {
      case '.css':
        contentType = 'text/css';
        break;
      case '.js':
        contentType = 'text/javascript';
        break;
    }
    
    res.writeHead(200, {'Content-Type': contentType});
    res.write(data);
    return res.end();
  });
}

// Function to set RGB color with PWM
function setRGBColor(red, green, blue) {
  // For Common Cathode RGB LED (direct PWM)
  redLed.pwmWrite(red);
  greenLed.pwmWrite(green);
  blueLed.pwmWrite(blue);
  
  // For Common Anode RGB LED (inverted PWM)
  // redLed.pwmWrite(255 - red);
  // greenLed.pwmWrite(255 - green);
  // blueLed.pwmWrite(255 - blue);
  
  currentColor = { red, green, blue };
  console.log(`Color set to RGB(${red}, ${green}, ${blue})`);
}

io.sockets.on('connection', (socket) => {
  console.log('Client connected');
  
  // Send current color to new client
  socket.emit('currentColor', currentColor);
  
  socket.on('rgbLed', (colorData) => {
    const red = Math.max(0, Math.min(255, colorData.red || 0));
    const green = Math.max(0, Math.min(255, colorData.green || 0));
    const blue = Math.max(0, Math.min(255, colorData.blue || 0));
    
    setRGBColor(red, green, blue);
    
    // Broadcast color change to all connected clients
    socket.broadcast.emit('currentColor', currentColor);
  });
  
  socket.on('disconnect', () => {
    console.log('Client disconnected');
  });
});

// Clean up on exit
process.on('SIGINT', () => {
  console.log('\nTurning off LEDs and cleaning up...');
  redLed.pwmWrite(0);
  greenLed.pwmWrite(0);
  blueLed.pwmWrite(0);
  
  setTimeout(() => {
    redLed.digitalWrite(0);
    greenLed.digitalWrite(0);
    blueLed.digitalWrite(0);
    process.exit();
  }, 100);
});

একটি সাধারণ ক্যাথোড RGB LED ব্যবহার করে

// Common Cathode Configuration
// In the setRGBColor function, use direct PWM values:
redLed.pwmWrite(red);
greenLed.pwmWrite(green);  
blueLed.pwmWrite(blue);

// Wiring for Common Cathode:
// - Longest pin (common cathode) to GND
// - Red pin to GPIO 17 with 220Ω resistor
// - Green pin to GPIO 27 with 220Ω resistor  
// - Blue pin to GPIO 22 with 220Ω resistor

একটি সাধারণ অ্যানোড RGB LED ব্যবহার করে

// Common Anode Configuration  
// In the setRGBColor function, use inverted PWM values:
redLed.pwmWrite(255 - red);
greenLed.pwmWrite(255 - green);
blueLed.pwmWrite(255 - blue);

// Wiring for Common Anode:
// - Longest pin (common anode) to 3.3V
// - Red pin to GPIO 17 with 220Ω resistor
// - Green pin to GPIO 27 with 220Ω resistor
// - Blue pin to GPIO 22 with 220Ω resistor

Raspberry Pi এবং Node.js WebSocket UI

এখন সময় এসেছে এইচটিএমএল যোগ করার যা ওয়েবসকেটের মাধ্যমে ব্যবহারকারীর ইনপুটকে অনুমতি দেয়।

এর জন্য আমরা চাই:

"পাবলিক" ফোল্ডারে যান:

pi@jassifteam:~/nodetest $ cd public

এবং একটি HTML ফাইল তৈরি করুন, rgb.html:

pi@jassifteam:~/nodetest/public $ nano rgb.html

rgb.html:

<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<style>
.slider {
  -webkit-appearance: none;
  width: 100%;
  height: 15px;
  border-radius: 5px;
  background: #d3d3d3;
  outline: none;
  opacity: 0.7;
  -webkit-transition: .2s;
  transition: opacity .2s;
}

.slider:hover {opacity: 1;}

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  cursor: pointer;
}

.slider::-moz-range-thumb {
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #4CAF50;
  cursor: pointer;
}
#redSlider::-webkit-slider-thumb {background: red;}
#redSlider::-moz-range-thumb {background: red;}
#greenSlider::-webkit-slider-thumb {background: green;}
#greenSlider::-moz-range-thumb {background: green;}
#blueSlider::-webkit-slider-thumb {background: blue;}
#blueSlider::-moz-range-thumb {background: blue;}
</style>
<body>

<div class="w3-container">
<h1>RGB Color</h1>
<div class="w3-cell-row">
<div class="w3-container w3-cell w3-mobile">
<p><input type="range" min="0" max="255" value="0" class="slider" id="redSlider"></p>
<p><input type="range" min="0" max="255" value="0" class="slider" id="greenSlider"></p>
<p><input type="range" min="0" max="255" value="0" class="slider" id="blueSlider"></p>
</div>
<div class="w3-container w3-cell w3-mobile" style="background-color:black" id="colorShow">
<div></div>
</div>
</div>
<p>Or pick a color: <input type="color" id="pickColor"></p>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script src="https://www.w3schools.com/lib/w3color.js"></script>
<script>
let socket = io(); //load socket.io-client and connect to the host that serves the page
let rgb = w3color("rgb(0,0,0)"); //we use the w3color.js library to keep the color as an object
window.addEventListener("load", function(){ //when page loads
  let rSlider = document.getElementById("redSlider");
  let gSlider = document.getElementById("greenSlider");
  let bSlider = document.getElementById("blueSlider");
  let picker = document.getElementById("pickColor");

  rSlider.addEventListener("change", function() { //add event listener for when red slider changes
    rgb.red = this.value; //update the RED color according to the slider
    colorShow.style.backgroundColor = rgb.toRgbString(); //update the "Current color"
    socket.emit("rgbLed", rgb); //send the updated color to RGB LED via WebSocket
  });
  gSlider.addEventListener("change", function() { //add event listener for when green slider changes
    rgb.green = this.value; //update the GREEN color according to the slider
    colorShow.style.backgroundColor = rgb.toRgbString(); //update the "Current color"
    socket.emit("rgbLed", rgb); //send the updated color to RGB LED via WebSocket
  });
  bSlider.addEventListener("change", function() { //add event listener for when blue slider changes
    rgb.blue = this.value;  //update the BLUE color according to the slider
    colorShow.style.backgroundColor = rgb.toRgbString(); //update the "Current color"
    socket.emit("rgbLed", rgb); //send the updated color to RGB LED via WebSocket
  });
  picker.addEventListener("input", function() { //add event listener for when colorpicker changes
    rgb.red = w3color(this.value).red; //Update the RED color according to the picker
    rgb.green = w3color(this.value).green; //Update the GREEN color according to the picker
    rgb.blue = w3color(this.value).blue; //Update the BLUE color according to the picker
    colorShow.style.backgroundColor = rgb.toRgbString();  //update the "Current color"
    rSlider.value = rgb.red;  //Update the RED slider position according to the picker
    gSlider.value = rgb.green;  //Update the GREEN slider position according to the picker
    bSlider.value = rgb.blue;  //Update the BLUE slider position according to the picker
   socket.emit("rgbLed", rgb);  //send the updated color to RGB LED via WebSocket
  });
});
</script>

</body>
</html>

"nodetest" ফোল্ডারে ফিরে যান:

pi@jassifteam:~/nodetest $ cd ..

কোড চালান:

pi@jassifteam:~ $ sudo node rgbws.js

⚠️দ্রষ্টব্য:

যেহেতু "পিগপিও" মডিউলটি পিগপিও সি লাইব্রেরি ব্যবহার করে, তাই হার্ডওয়্যার পেরিফেরালগুলি (যেমন GPIO) অ্যাক্সেস করার জন্য এটির রুট/সুডো সুবিধার প্রয়োজন।

http://[RaspberryPi_IP]:8080/

এখন ব্যবহারকারীর ইনপুটের উপর নির্ভর করে RGB LED রঙ পরিবর্তন করা উচিত।

Ctrl+c দিয়ে প্রোগ্রাম শেষ করুন।

অনুশীলন করুন

Node.js PWM (- ) ? .

অনফ মডিউল
✗ ভুল! অনফ মডিউল PWM সমর্থন করে না, এটি শুধুমাত্র অন/অফ ফাংশনের জন্য
পিগপিও মডিউল
✓ ঠিক আছে! পিগপিও মডিউল PWM অপারেশন সমর্থন করে এবং RGB LED-এর জন্য উপযুক্ত
gpio মডিউল
✗ ভুল! "gpio" Node.js-এ একটি বৈধ মডিউল নয়
pwm মডিউল
✗ ভুল! "pwm" Node.js-এ একটি বৈধ মডিউল নয়